infra(cpb): add dedicated role provisioning and schema setup#124
infra(cpb): add dedicated role provisioning and schema setup#124SashkoMarchuk merged 9 commits intomainfrom
Conversation
…ple Bot Replace the old setup script that required postgres admin access and CREATEROLE with a version that uses temporal user (CREATEDB) and grants to existing n8n user. Add complete 6-table schema (cycles, opt_in_responses, pairings, pair_history, interactions, admin_reports) with idempotent IF NOT EXISTS, triggers, and indexes. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Fix two filename references in header comments flagged by CodeRabbit: - setup-db.sh usage example: cpb-setup-db.sh → cpb/setup-db.sh - init-schema.sql usage example: cpb-init-schema.sql → init-schema.sql Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Refactor schema grant error handling from fragile `cmd && echo || { ... }`
to proper if/then/else. Prevents false error-path execution if echo fails.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace temporal-based DB setup with a two-script architecture: - create-role.sh: one-time provisioning using RDS master password to create cpb_app role and cpb_bot database - setup-db.sh: repeatable schema setup connecting as cpb_app Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add REASSIGN OWNED step in create-role.sh to transfer object ownership (tables, sequences, functions) after database ownership transfer - Fail fast in setup-db.sh when table count != 6 (exit 1, not warning) - Add UNIQUE(cycle_id, person_a_id, person_b_id) to pairings table - Replace independent touchpoint/action CHECKs with composite constraint that enforces valid combinations (e.g. blocks opt_in + satisfied) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
One report per cycle is the correct invariant — enforce at DB level. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add updated_at + trigger to pairings table (6 mutable columns had no modification timestamp, breaking pattern of other mutable tables) - Remove 3 redundant indexes whose leading columns are already covered by UNIQUE constraints (opt_in_responses, pairings, admin_reports) - Fix misleading "-v" hint in setup-db.sh error message Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Enforce YYYY-MM format via regex to prevent invalid values like '2026-13' or 'foobar' from being inserted. Flagged independently by two /ultra XL agents (D2-contrarian, V2-schema). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Capture and display the actual psql error on connection failure instead of suppressing it. Operators now see the real diagnostic (wrong password, host unreachable, DB missing) instead of generic "Cannot connect" message. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
📝 WalkthroughWalkthroughReorganized PostgreSQL provisioning workflow from a single monolithic script to a two-stage process: moved from Changes
Sequence DiagramsequenceDiagram
participant Admin as Administrator
participant CPBCreate as create-role.sh
participant RDS as RDS PostgreSQL
participant CPBSetup as setup-db.sh
participant SchemaFile as init-schema.sql
Admin->>CPBCreate: Run (POSTGRES_PASSWORD_MASTER)
CPBCreate->>RDS: Connect with master credentials
CPBCreate->>RDS: Create/update cpb_app role
CPBCreate->>RDS: Create cpb_bot database
CPBCreate->>RDS: Transfer ownership to cpb_app
CPBCreate->>RDS: Reassign existing objects ownership
CPBCreate->>RDS: Grant privileges to cpb_app
RDS-->>CPBCreate: Provisioning complete
Admin->>CPBSetup: Run (POSTGRES_PASSWORD_CPB)
CPBSetup->>SchemaFile: Resolve schema file path
CPBSetup->>RDS: Connect with cpb_app credentials
CPBSetup->>RDS: Verify connectivity (SELECT 1)
CPBSetup->>SchemaFile: Read and execute schema
SchemaFile->>RDS: Create tables, triggers, indexes
RDS-->>SchemaFile: Schema applied
CPBSetup->>RDS: Verify 6 tables exist
RDS-->>CPBSetup: Schema initialization complete
Estimated code review effort🎯 4 (Complex) | ⏱️ ~50 minutes Possibly related PRs
Suggested labels
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
🤖 CodeRabbit AI Review AvailableTo request a code review from CodeRabbit AI, add CodeRabbit will analyze your code and provide feedback on:
Note: Reviews are only performed when |
|
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
There was a problem hiding this comment.
🧹 Nitpick comments (1)
scripts/cpb/create-role.sh (1)
49-65: Validates all identifiers including master user.Good that
MASTER_USERis also validated since it's interpolated into SQL statements. The validation function is duplicated fromsetup-db.sh— consider extracting to a shared shell library if more CPB scripts are added in the future.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@scripts/cpb/create-role.sh` around lines 49 - 65, The script duplicates the validate_pg_identifier function (used to validate MASTER_USER, CPB_USER, CPB_DB) which is already in setup-db.sh; extract validate_pg_identifier into a shared shell library (e.g., lib-db.sh) and source it from both scripts, then remove the duplicate function from create-role.sh and keep the calls validate_pg_identifier "$MASTER_USER" "POSTGRES_USER_MASTER", validate_pg_identifier "$CPB_USER" "POSTGRES_USER_CPB", validate_pg_identifier "$CPB_DB" "POSTGRES_DB_CPB" unchanged so identifier validation remains enforced.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@scripts/cpb/create-role.sh`:
- Around line 49-65: The script duplicates the validate_pg_identifier function
(used to validate MASTER_USER, CPB_USER, CPB_DB) which is already in
setup-db.sh; extract validate_pg_identifier into a shared shell library (e.g.,
lib-db.sh) and source it from both scripts, then remove the duplicate function
from create-role.sh and keep the calls validate_pg_identifier "$MASTER_USER"
"POSTGRES_USER_MASTER", validate_pg_identifier "$CPB_USER" "POSTGRES_USER_CPB",
validate_pg_identifier "$CPB_DB" "POSTGRES_DB_CPB" unchanged so identifier
validation remains enforced.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yml
Review profile: CHILL
Plan: Pro
Run ID: 6945a2c6-5b67-4a4c-9970-430faf220295
📒 Files selected for processing (5)
.env.examplescripts/cpb-setup-db.shscripts/cpb/create-role.shscripts/cpb/setup-db.shsql/cpb/init-schema.sql
💤 Files with no reviewable changes (1)
- scripts/cpb-setup-db.sh



Summary
cpb_approlescripts/cpb/create-role.sh(NEW): One-time provisioning using RDS master password — createscpb_approle,cpb_botdatabase, transfers ownership fromtemporalif needed, grants all privilegesscripts/cpb/setup-db.sh(REWRITTEN): Repeatable schema setup connecting ascpb_app— appliesinit-schema.sql, verifies all 6 tablessql/cpb/init-schema.sql(NEW): Complete 6-table schema for CPB Slack bot (cycles, opt_in_responses, pairings, pair_history, interactions, admin_reports)scripts/cpb-setup-db.shthat required temporal user with CREATEDBPOSTGRES_PASSWORD_MASTERto.env.example(commented out, one-time use)Operational Workflow
Security
:?— immediate fail if unset, no fallbacksvalidate_pg_identifier()on all SQL identifiers (regex + length check)$$rejection on passwordsset -eo pipefail+ON_ERROR_STOP=1on both scriptsTest plan
bash -nsyntax check passes on both scriptscreate-role.shagainst RDS — role and database createdcreate-role.shagain — idempotent, no errors, password updatedsetup-db.sh— all 6 tables createdsetup-db.shagain — idempotent, no errorscpb_appownscpb_botdatabaseinit-schema.sql(triggers, indexes, constraints)Supersedes #123
Summary by CodeRabbit
Release Notes
Chores
New Features